#include <graphics.h>  // 包含 EGE 图形库头文件
#include <ege/sys_edit.h> 
#include <math.h>      // 用于数学计算
#include <stdio.h>
#include <string.h>


void biaopan(int centerX, int centerY, int radius);//  表盘界面 
void kedu(int centerX, int centerY, int radius); //刻度 
void wenzi(int centerX, int centerY, int radius);//文字
void zhizhen(int rx, int ry);//指针
void drawScrew(float x, float y, float r);//画螺丝
void rotate_point(int cx, int cy, int x, int y, float angle, int* outX, int* outY);//计算角度位置
void drawGauge(int centerX, int centerY, int radius);



void drawScrew(float x, float y, float r) //画螺丝
{
	// 计算比例因子 (基于原始r=280的比例)
	const float scale = r / 280.0f;
	
	// 螺丝位置偏移量 (比例化)
	float offset = 20.0f * scale;
	float dx[4] = {offset - r, r - offset, offset - r, r - offset};
	float dy[4] = {offset - r, r - offset, r - offset, offset - r};
	
	// 螺丝绘制
	for(int i = 0; i < 4; ++i) 
	{
		dx[i] += x;
		dy[i] += y;
		
		// 外圆部分 (比例化尺寸)
		float screwRadius = 30.2f * scale;
		
		setcolor(EGERGB(200, 200, 200));
		setfillcolor(EGERGB(200, 200, 200));
		sector(dx[i], dy[i], 180, 360, screwRadius, screwRadius);  // 下半圆
		
		setcolor(EGERGB(50, 50, 50));
		setfillcolor(EGERGB(50, 50, 50));
		sector(dx[i], dy[i], 0, 180, screwRadius, screwRadius);    // 上半圆
		
		// 中心圆 (比例化)
		setfillcolor(EGERGB(170, 170, 170));
		ege_fillcircle(dx[i], dy[i], 30.0f * scale);
	}
	
	// 十字线绘制 (比例化)
	for(int i = 0; i < 4; ++i) 
	{
		setcolor(BLACK);
		setlinestyle(SOLID_LINE, 0, static_cast<int>(7 * scale));  // 线宽比例化
		
		float lineLength = 16.0f * scale;
		ege_line(dx[i] - lineLength, dy[i], dx[i] + lineLength, dy[i]);  // 横线
		ege_line(dx[i], dy[i] - lineLength, dx[i], dy[i] + lineLength);  // 竖线
	}
}


void biaopan(int centerX, int centerY, int radius) // 表盘界面(比例化版本)
{
	// 计算比例因子 (基于原始radius=280的比例)
	const float scale = radius / 280.0f;
	
	// 比例化参数
	const int sechang = static_cast<int>(20 * scale);
	const float outer_ring1 = radius + 27 * scale;
	const float outer_ring2 = radius + 20 * scale;
	const float outer_ring3 = radius + 17 * scale;
	const float inner_ring = radius - sechang;
	const float mid_ring = radius - sechang/2;
	
	cleardevice();
	setcolor(EGERGB(110, 110, 110));
	// 绘制一个圆
	circle(centerX, centerY, radius);
	
	// 第一层外环
	setcolor(EGERGB(30, 30, 30));
	setfillcolor(EGERGB(30, 30, 30));
	sector(centerX, centerY, -20, 200, outer_ring1, outer_ring1);
	
	for(int i = 0; i <= 30; i++) {
		setcolor(EGERGB(20+i, 20+i, 20+i));
		setfillcolor(EGERGB(20+i, 20+i, 20+i));
		sector(centerX, centerY, 200+i*2, 210+i*2, outer_ring1, outer_ring1);
	}
	for(int i = 0; i <= 30; i++) {
		setcolor(EGERGB(20+i, 20+i, 20+i));
		setfillcolor(EGERGB(20+i, 20+i, 20+i));
		sector(centerX, centerY, 330-i*2, 340-i*2, outer_ring1, outer_ring1);
	}
	
	// 第二层外环
	setcolor(EGERGB(10, 10, 10));
	setfillcolor(EGERGB(10, 10, 10));
	sector(centerX, centerY, 0, 360, outer_ring2, outer_ring2);
	
	// 第三层外环
	setcolor(EGERGB(20, 20, 20));
	setfillcolor(EGERGB(20, 20, 20));
	sector(centerX, centerY, -20, 200, outer_ring3, outer_ring3);
	
	for(int i = 0; i <= 30; i++) {
		setcolor(EGERGB(20+i, 20+i, 20+i));
		setfillcolor(EGERGB(20+i, 20+i, 20+i));
		sector(centerX, centerY, 200+i*2, 210+i*2, outer_ring3, outer_ring3);
	}
	for(int i = 0; i <= 30; i++) {
		setcolor(EGERGB(20+i, 20+i, 20+i));
		setfillcolor(EGERGB(20+i, 20+i, 20+i));
		sector(centerX, centerY, 330-i*2, 340-i*2, outer_ring3, outer_ring3);
	}
	
	// 渐变效果环
	for(int i = 0; i <= 30; i++) {
		setcolor(EGERGB(60+i, 60+i, 60+i));
		setfillcolor(EGERGB(60+i, 60+i, 60+i));
		float current_radius = radius + i * 0.14f * scale;
		sector(centerX, centerY, 200+i*2, 210+i*2, current_radius, current_radius);
	}
	for(int i = 0; i <= 30; i++) {
		setcolor(EGERGB(60+i, 60+i, 60+i));
		setfillcolor(EGERGB(60+i, 60+i, 60+i));
		float current_radius = radius + i * 0.14f * scale;
		sector(centerX, centerY, 330-i*2, 340-i*2, current_radius, current_radius);
	}
	
	// 中心环
	setcolor(EGERGB(10, 10, 10));
	setfillcolor(EGERGB(10, 10, 10));
	sector(centerX, centerY, 0, 360, radius + 2 * scale, radius + 2 * scale);
	
	setcolor(EGERGB(28, 28, 28));
	setfillcolor(EGERGB(28, 28, 28));
	sector(centerX, centerY, 0, 360, radius, radius);
	
	// 彩色区域
	setcolor(EGERGB(16, 75, 16));
	setfillcolor(EGERGB(16, 75, 16));
	sector(centerX, centerY, 183, 372, radius, radius);
	
	setcolor(WHITE);
	setfillcolor(WHITE);
	sector(centerX, centerY, 291, 372, mid_ring, mid_ring);
	
	setcolor(YELLOW);
	setfillcolor(YELLOW);
	sector(centerX, centerY, 147, 183, radius, radius);
	
	// 最内环
	setcolor(EGERGB(35, 36, 35));
	setfillcolor(EGERGB(35, 36, 35));
	sector(centerX, centerY, 0, 360, inner_ring, inner_ring);
}


void kedu(int centerX, int centerY, int radius) // 刻度(比例化版本)
{
	// 计算比例因子 (基于原始radius=280的比例)
	const float scale = radius / 280.0f;
	
	// 比例化参数
	const int xianchang = static_cast<int>(30 * scale);  // 长刻度长度
	const int xianduan = static_cast<int>(23 * scale);   // 短刻度长度
	const int textOffset = static_cast<int>(40 * scale); // 文本偏移量
	const int fontHeight1 = static_cast<int>(50 * scale); // 大字体高度

	
	// 绘制刻度
	setcolor(BLACK);
	int p = 0;
	char a[3] = "";
	char b[4] = "";
	a[0] = '4'; a[1] = '0';
	b[0] = '1'; b[1] = '0'; b[2] = '0';
	
	setlinewidth(static_cast<int>(3 * scale));
	
	// 第一个循环：绘制较粗的线条（通过绘制多条线实现）
	for (double i = 15; i <= 303; i += 18) {
		double angle1 = 3.14159265358979323846 / 180;
		double angle = i * angle1;               // 将角度转换为弧度
		int x1 = centerX + (radius - xianchang) * sin(angle);
		int y1 = centerY - (radius - xianchang) * cos(angle);
		int x2 = centerX + radius * sin(angle);
		int y2 = centerY - radius * cos(angle);
		
		// 特殊刻度线（红线和蓝线）
		if(i == 15 + 18 * 4) {
			setcolor(RED);
			line(centerX + radius / 2 * sin(angle+angle1*9.5),
				centerY - radius / 2 * cos(angle+angle1*9.5),
				centerX + radius * sin(angle+angle1*9.5),
				centerY - radius * cos(angle+angle1*9.5));
		}
		if(i == 15 + 18 * 6) {
			setcolor(EGERGB(8, 80, 160));
			line(centerX, centerY,
				centerX + radius * sin(angle+angle1*1),
				centerY - radius * cos(angle+angle1*1));
		}
		
		// 绘制刻度线
		setcolor(WHITE);
		line(x1, y1, x2, y2);
		
		// 刻度数值
		int textX = centerX + (radius - xianchang - textOffset) * sin(angle);
		int textY = centerY - (radius - xianchang - textOffset) * cos(angle);
		
		int textWidth = 0, textHeight = 0;
		if (a[0] <= '9' && p % 2 == 0) {
			setfont(fontHeight1, static_cast<int>(30 * scale), "黑体");
			textWidth = textwidth(a);
			textHeight = textheight(a);
			setcolor(WHITE);
			setbkmode(TRANSPARENT);
			outtextxy(textX - textWidth / 2, textY - textHeight / 2, a);
			a[0]++; a[0]++;
		} else if (p % 2 == 0) {
			setfont(fontHeight1, static_cast<int>(30 * scale), "黑体");
			textWidth = textwidth(b);
			textHeight = textheight(b);
			setcolor(WHITE);
			setbkmode(TRANSPARENT);
			outtextxy(textX - textWidth / 2, textY - textHeight / 2, b);
			b[1]++; b[1]++;
			if (b[1] > '9') { b[1] = '2'; b[0]++; }
		}
		p++;
	}
	
	b[1]='6';
	
	// 右上角刻度
	setcolor(WHITE);  
	for (double i = 312; i <= 345; i += 9) {
		float angle = i * 3.14159 / 180;
		int x1 = centerX + (radius - xianchang) * sin(angle);
		int y1 = centerY - (radius - xianchang) * cos(angle);
		int x2 = centerX + radius * sin(angle);
		int y2 = centerY - radius * cos(angle);
		
		line(x1, y1, x2, y2);
		
		if(i > 335) {
			int textX = centerX + (radius - xianchang - textOffset) * sin(angle);
			int textY = centerY - (radius - xianchang - textOffset) * cos(angle);
			
			setfont(fontHeight1, static_cast<int>(30 * scale), "黑体");
			int textWidth = textwidth(b);
			int textHeight = textheight(b);
			setcolor(WHITE);
			setbkmode(TRANSPARENT);
			outtextxy(textX - textWidth / 2, textY - textHeight / 2, b);
		}
	}
	
	// 第二个循环：绘制较细的线条
	setcolor(WHITE);  
	for (double i = 24; i <= 303; i += 18) {
		float angle = i * 3.14159 / 180;
		int x1 = centerX + (radius - xianduan) * sin(angle);
		int y1 = centerY - (radius - xianduan) * cos(angle);
		int x2 = centerX + radius * sin(angle);
		int y2 = centerY - radius * cos(angle);
		
		setlinestyle(PS_SOLID, static_cast<int>(1 * scale));
		line(x1, y1, x2, y2);
	}
	
	// 右上角细刻度
	for (double i = 307.5; i <= 340; i += 9) {
		float angle = i * 3.14159 / 180;
		int x1 = centerX + (radius - xianduan) * sin(angle);
		int y1 = centerY - (radius - xianduan) * cos(angle);
		int x2 = centerX + radius * sin(angle);
		int y2 = centerY - radius * cos(angle);
		
		line(x1, y1, x2, y2);
	}    
	
	
	// 边框圆
	setcolor(BLACK);
	circle(centerX, centerY, radius);
	setcolor(BLACK);
	circle(centerX, centerY, static_cast<int>(radius + 25.1 * scale));
}


void wenzi(int centerX, int centerY, int radius) // 文字(严格比例化版本)
{
	// 计算比例因子 (基于原始radius=280的比例)
	const float scale = radius / 280.0f;
	
	// 设置主文字(KNOTS)
	int main_font_height = static_cast<int>(50 * scale);
	setfont(main_font_height, 0, "宋体");
	setcolor(WHITE);
	setbkmode(TRANSPARENT);
	
	// 严格保持原始位置比例计算
	int knots_x = centerX - 65 * scale ;
	int knots_y = centerY - 105 * scale;
	outtextxy(knots_x, knots_y, "KNOTS");
	
	// 设置副文字(AIRSPEED)
	int sub_font_height = static_cast<int>(30 * scale);
	setfont(sub_font_height, 0, "宋体");
	setcolor(WHITE);
	setbkmode(TRANSPARENT);
	
	// 严格保持原始位置比例计算 
	int airspeed_x = centerX - 65 * scale ;
	int airspeed_y = centerY - 60 * scale;
	outtextxy(airspeed_x, airspeed_y, "AIRSPEED");
}


void rotate_point(int cx, int cy, int x, int y, float angle, int* outX, int* outY)// 旋转坐标计算函数
{
	// 将点平移到原点
	x -= cx;
	y -= cy;
	
	// 计算旋转后的坐标
	*outX = cx + (int)(x * cos(angle) - y * sin(angle));
	*outY = cy + (int)(x * sin(angle) + y * cos(angle));
}


void zhizhen(int cx, int cy, float angle, int radius)// 绘制旋转指针
{
	// 计算比例因子 (基于原始设计为280半径的表盘)
	const float scale = radius / 280.0f;
	
	// 指针各部分尺寸定义
	const float pointer_width = 14.0f * scale;    // 指针宽度
	const float pointer_length = 230.0f * scale;  // 指针总长度
	const float pointer_tail_length = 80.0f * scale; // 指针尾部长度
	const float pointer_tip_length = 50.0f * scale;  // 指针尖端超出主体的长度
	
	// 指针各部分坐标（比例化后）
	// 指针主体矩形坐标
	int rect_left = cx - static_cast<int>(pointer_width/2);
	int rect_top = cy - static_cast<int>(pointer_length - pointer_tip_length);
	int rect_right = cx + static_cast<int>(pointer_width/2);
	int rect_bottom = cy - static_cast<int>(pointer_tip_length);
	
	// 指针三角形坐标
	int tri_points[3][2] = {
		{cx - static_cast<int>(pointer_width/2), cy - static_cast<int>(pointer_length - pointer_tip_length)},
		{cx + static_cast<int>(pointer_width/2), cy - static_cast<int>(pointer_length - pointer_tip_length)},
		{cx, cy - static_cast<int>(pointer_length)}
	};
	
	// 指针底部矩形坐标
	int bottom_rect_left = cx - static_cast<int>(pointer_width/2);
	int bottom_rect_top = cy;
	int bottom_rect_right = cx + static_cast<int>(pointer_width/2);
	int bottom_rect_bottom = cy - static_cast<int>(pointer_tip_length);
	
	// 指针尾部坐标
	int tail_rect_left = cx - static_cast<int>(pointer_width/2);
	int tail_rect_top = cy;
	int tail_rect_right = cx + static_cast<int>(pointer_width/2);
	int tail_rect_bottom = cy + static_cast<int>(pointer_tail_length);
	
	// 旋转后的坐标
	int rotated_rect[4][2];
	int rotated_tri[3][2];
	int rotated_bottom_rect[4][2];
	int rotated_tail_rect[4][2];
	
	// 计算旋转后的矩形坐标
	rotate_point(cx, cy, rect_left, rect_top, angle, &rotated_rect[0][0], &rotated_rect[0][1]);
	rotate_point(cx, cy, rect_right, rect_top, angle, &rotated_rect[1][0], &rotated_rect[1][1]);
	rotate_point(cx, cy, rect_right, rect_bottom, angle, &rotated_rect[2][0], &rotated_rect[2][1]);
	rotate_point(cx, cy, rect_left, rect_bottom, angle, &rotated_rect[3][0], &rotated_rect[3][1]);
	
	// 计算旋转后的三角形坐标
	for (int i = 0; i < 3; i++) {
		rotate_point(cx, cy, tri_points[i][0], tri_points[i][1], angle, 
			&rotated_tri[i][0], &rotated_tri[i][1]);
	}
	
	// 绘制指针主体（白色部分）
	setfillcolor(WHITE);
	setcolor(WHITE);
	ege_point rect_points[4];
	for (int i = 0; i < 4; i++) {
		rect_points[i].x = rotated_rect[i][0];
		rect_points[i].y = rotated_rect[i][1];
	}
	ege_fillpoly(4, rect_points);
	
	// 绘制指针尖端（三角形）
	ege_point tri_points_ege[3];
	for (int i = 0; i < 3; i++) {
		tri_points_ege[i].x = rotated_tri[i][0];
		tri_points_ege[i].y = rotated_tri[i][1];
	}
	ege_fillpoly(3, tri_points_ege);
	
	// 绘制指针底部（深色部分）
	setfillcolor(EGERGB(17,14,11));
	setcolor(EGERGB(17,14,11));
	
	// 计算并绘制底部矩形
	rotate_point(cx, cy, bottom_rect_left, bottom_rect_top, angle, 
		&rotated_bottom_rect[0][0], &rotated_bottom_rect[0][1]);
	rotate_point(cx, cy, bottom_rect_right, bottom_rect_top, angle, 
		&rotated_bottom_rect[1][0], &rotated_bottom_rect[1][1]);
	rotate_point(cx, cy, bottom_rect_right, bottom_rect_bottom, angle, 
		&rotated_bottom_rect[2][0], &rotated_bottom_rect[2][1]);
	rotate_point(cx, cy, bottom_rect_left, bottom_rect_bottom, angle, 
		&rotated_bottom_rect[3][0], &rotated_bottom_rect[3][1]);
	
	ege_point bottom_points[4];
	for (int i = 0; i < 4; i++) {
		bottom_points[i].x = rotated_bottom_rect[i][0];
		bottom_points[i].y = rotated_bottom_rect[i][1];
	}
	ege_fillpoly(4, bottom_points);
	
	// 计算并绘制尾部矩形
	rotate_point(cx, cy, tail_rect_left, tail_rect_top, angle, 
		&rotated_tail_rect[0][0], &rotated_tail_rect[0][1]);
	rotate_point(cx, cy, tail_rect_right, tail_rect_top, angle, 
		&rotated_tail_rect[1][0], &rotated_tail_rect[1][1]);
	rotate_point(cx, cy, tail_rect_right, tail_rect_bottom, angle, 
		&rotated_tail_rect[2][0], &rotated_tail_rect[2][1]);
	rotate_point(cx, cy, tail_rect_left, tail_rect_bottom, angle, 
		&rotated_tail_rect[3][0], &rotated_tail_rect[3][1]);
	
	ege_point tail_points[4];
	for (int i = 0; i < 4; i++) {
		tail_points[i].x = rotated_tail_rect[i][0];
		tail_points[i].y = rotated_tail_rect[i][1];
	}
	ege_fillpoly(4, tail_points);
	
	// 绘制中心渐变圆点
	int center_circle_size = static_cast<int>(25 * scale);
	for(int i = 0; i < center_circle_size; i++){
		setfillcolor(EGERGB(17+i,14+i,11+i));
		setcolor(EGERGB(17+i,14+i,11+i));
		fillellipse(cx, cy, center_circle_size-i, center_circle_size-i);
	}
	
	// 绘制尾部圆点
	int tail_circle_x, tail_circle_y;
	rotate_point(cx, cy, cx, cy + static_cast<int>(pointer_tail_length), angle, &tail_circle_x, &tail_circle_y);
	int tail_circle_size = static_cast<int>(13 * scale);
	for(int i = 0; i < tail_circle_size; i++){
		setfillcolor(EGERGB(17+2*i,14+2*i,11+2*i));
		setcolor(EGERGB(17+2*i,14+2*i,11+2*i));
		fillellipse(tail_circle_x, tail_circle_y, tail_circle_size-i, tail_circle_size-i);
	}
}


void drawGauge(int centerX, int centerY, int radius,float angle) // 绘制圆形仪表盘
{
	
	biaopan(centerX, centerY, radius);
	drawScrew((float)centerX,(float)centerY, radius);
	kedu(centerX, centerY, radius); 
	wenzi(centerX,centerY,radius);
	zhizhen(centerX,centerY,angle,radius);

	
}



int main() 
{
	// 初始化图形窗口
	initgraph(1200, 800);  
	setrendermode(RENDER_MANUAL);// 设置为手动渲染模式  双缓冲技术 防止界面刷新时闪烁
	
	setbkcolor(EGERGB(110, 110, 110));
	cleardevice();
	
	// 仪表盘参数
	int centerX = 600;  // 仪表盘中心 x 坐标
	int centerY = 400;  // 仪表盘中心 y 坐标
	int radius = 280;   // 仪表盘半径

	float i=0;

	
	// 进入主循环，等待用户关闭窗口
	for (; is_run(); delay_fps(60)) { 
		// 绘制仪表盘
		i+=0.1;
		if(i==360){i=0;}
		float angle =  i  * 3.14159 / 180;
		cleardevice();
	    drawGauge(centerX, centerY, radius,angle);
	}
	
	// 关闭图形窗口
	closegraph();
	return 0;
}
